package tosp.search;

import java.util.Vector;

import org.apache.log4j.Logger;

import tosp.HistoryMachine;
import tosp.JobSequence;
import tosp.job.Job;

public class ThreeSwitchSearch extends LocalSearchAdapter {

	static Logger log = Logger.getLogger(ThreeSwitchSearch.class);
	
	public ThreeSwitchSearch(HistoryMachine m) {
		super(m);
	}

	@Override
	public JobSequence[] getNeighbors(JobSequence js) {
		Vector<JobSequence> threeset = new Vector<JobSequence>();
		for (int j = 0; j < js.getNumberOfJobs()-2; j++) {
			threeset.add(get231Neighbor(js, j));
			threeset.add(get312Neighbor(js, j));
		}
		threeset.trimToSize();
		log.debug("Generated a Total of "+ threeset.size() +" Neighbors");
		return threeset.toArray(new JobSequence[threeset.size()]);
	}
	
	public JobSequence get231Neighbor(JobSequence js, int o) {
		Vector<Job> ret = new Vector<Job>();
		for (int j = 0; j < o; j++) {
			ret.add(js.getJob(j));
		}
		ret.add(js.getJob(o+1));
		ret.add(js.getJob(o+2));
		ret.add(js.getJob(o));
		for (int j=o+3; j<js.getNumberOfJobs(); j++) {
			ret.add(js.getJob(j));
		}
		JobSequence newjs = new JobSequence(ret,true);
		log.trace("Generated new Neighbor: "+newjs.getSeqAsString());
		return newjs;
	}
	
	public JobSequence get312Neighbor(JobSequence js, int o) {
		Vector<Job> ret = new Vector<Job>();
		for (int j = 0; j < o; j++) {
			ret.add(js.getJob(j));
		}
		ret.add(js.getJob(o+2));
		ret.add(js.getJob(o));
		ret.add(js.getJob(o+1));
		for (int j=o+3; j<js.getNumberOfJobs(); j++) {
			ret.add(js.getJob(j));
		}
		JobSequence newjs = new JobSequence(ret,true);
		log.trace("Generated new Neighbor: "+newjs.getSeqAsString());
		return newjs;
	}
	
	public int getNeighborSize(JobSequence j) {
		return j.getSize();
	}
	
}
